﻿package com.edzis.reliefglobe {
	import flash.display.BitmapData;
	import flash.display.MovieClip;
	import flash.events.MouseEvent;
	import org.papervision3d.core.geom.renderables.Triangle3D;
	import org.papervision3d.core.geom.renderables.Vertex3D;
	import org.papervision3d.core.math.NumberUV;
	import org.papervision3d.materials.BitmapMaterial;
	import org.papervision3d.materials.MovieMaterial;
	import org.papervision3d.materials.utils.BitmapMaterialTools;
	import org.papervision3d.objects.primitives.Sphere;
	import org.papervision3d.Papervision3D;
	
	public class DisplacementSphere extends Sphere {
		
		
		[Embed(source='../../../../lib/reliefglobe_library.swf', symbol='displacement_32')]
		private var displacement_32	:Class;
		
		[Embed(source='../../../../lib/reliefglobe_library.swf', symbol='displacement_16')]
		private var displacement_16	:Class;
		
		[Embed(source='../../../../lib/reliefglobe_library.swf', symbol='GlobeButtons_design')]
		private var globeButtons	:Class;
		
		private var segW			:int = 32;
		private var segH			:int = 32;
		private var dArr			:Array;
		private var mapData			:BitmapData;
		
		public function DisplacementSphere() {
			
			mapData = BitmapMaterialTools.getTexture(displacement_32);
			
			var globeButtonsMc:MovieClip = new globeButtons() as MovieClip;
			var btn:MovieClip;
			for (var i:int = 0; i < globeButtonsMc.numChildren; i++) {
				if (globeButtonsMc.getChildAt(i) is MovieClip) {
					btn = globeButtonsMc.getChildAt(i) as MovieClip;
				//	btn.alpha = 0.5;
					btn.buttonMode = true;
					btn.addEventListener(MouseEvent.CLICK, onIslandClicked);
				}
			}
			var sphereMaterial:MovieMaterial = new MovieMaterial(globeButtonsMc, false, false, false);
			sphereMaterial.interactive = true;
		
			applyDisplaceMap();
		
			super(sphereMaterial, 500, segW, segH);
		}
		
		private function onIslandClicked(e:MouseEvent):void {
			ArthropodDebug.log("onIslandClicked");
		}
		
		public function applyDisplaceMap():void {
			dArr = new Array();
			for(var i:int=0; i< segW; i++) {
				dArr[i] = new Array(); 
				for (var j:uint = 0; j <= segH; j++) {
					dArr[i][j] = 1 + Number( mapData.getPixel( i, segH - j) >> 16 )/4000 ;
				}
			}
		}
		
		override protected function buildSphere(fRadius:Number):void {
			var i:Number, j:Number, k:Number;
			var iHor:Number = Math.max(3,this.segW);
			var iVer:Number = Math.max(2,this.segH);
			var aVertice:Array = this.geometry.vertices;
			var aFace:Array = this.geometry.faces;
			var aVtc:Array = new Array();
			for (j=0;j<(iVer+1);j++) { // vertical
				var fRad1:Number = Number(j/iVer);
				var fZ:Number = -fRadius*Math.cos(fRad1*Math.PI);
				var fRds:Number = fRadius*Math.sin(fRad1*Math.PI);
				var aRow:Array = new Array();
				var oVtx:Vertex3D;
				for (i=0;i<iHor;i++) { // horizontal
					var fRad2:Number = Number(2*i/iHor);
					//var fX:Number = fRds*Math.sin(fRad2*Math.PI);
					//var fY:Number = fRds * Math.cos(fRad2 * Math.PI);
					var fX:Number = fRds*Math.sin(fRad2*Math.PI)* dArr[i][j];
					var fY:Number = fRds * Math.cos(fRad2 * Math.PI) * dArr[i][j];
					fZ = fZ;
					if (!((j==0||j==iVer)&&i>0)) { // top||bottom = 1 vertex
						oVtx = new Vertex3D(fY,fZ * dArr[i][j],fX);
						aVertice.push(oVtx);
					}
					aRow.push(oVtx);
				}
				aVtc.push(aRow);
			}
			var iVerNum:int = aVtc.length;
			for (j=0;j<iVerNum;j++) {
				var iHorNum:int = aVtc[j].length;
				if (j>0) { // &&i>=0
					for (i=0;i<iHorNum;i++) {
						// select vertices
						var bEnd:Boolean = i==(iHorNum-0);
						var aP1:Vertex3D = aVtc[j][bEnd?0:i];
						var aP2:Vertex3D = aVtc[j][(i==0?iHorNum:i)-1];
						var aP3:Vertex3D = aVtc[j-1][(i==0?iHorNum:i)-1];
						var aP4:Vertex3D = aVtc[j-1][bEnd?0:i];
						// uv
						/*
						 * fix applied as suggested by Philippe to correct the uv mapping on a sphere
						 * */
						var fJ0:Number = j		/ (iVerNum-1);
						var fJ1:Number = (j-1)	/ (iVerNum-1);
						var fI0:Number = (i+1)	/ iHorNum;
						var fI1:Number = i		/ iHorNum;
						var aP4uv:NumberUV = new NumberUV(fI0,fJ1);
						var aP1uv:NumberUV = new NumberUV(fI0,fJ0);
						var aP2uv:NumberUV = new NumberUV(fI1,fJ0);
						var aP3uv:NumberUV = new NumberUV(fI1,fJ1);
						// 2 faces
						if (j<(aVtc.length-1))	aFace.push( new Triangle3D(this, new Array(aP1,aP2,aP3), material, new Array(aP1uv,aP2uv,aP3uv)) );
						if (j>1)				aFace.push( new Triangle3D(this, new Array(aP1,aP3,aP4), material, new Array(aP1uv,aP3uv,aP4uv)) );
	
					}
				}
			}
			for each(var t:Triangle3D in aFace){
				t.renderCommand.create = createRenderTriangle;
			}
			
			this.geometry.ready = true;
			
			if(Papervision3D.useRIGHTHANDED)
				this.geometry.flipFaces();
		}
		
	}
	
}